#include "OgreGLESDepthBuffer.h"
#include "OgreGLESHardwarePixelBuffer.h"
#include "OgreGLESRenderSystem.h"
#include "OgreGLESFrameBufferObject.h"

namespace Ogre
{
	GLESDepthBuffer::GLESDepthBuffer(uint16 poolId, GLESRenderSystem* renderSystem, GLESContext* creatorContext,
									 GLESRenderBuffer* depth, GLESRenderBuffer* stencil,
									 uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuantity,
									 bool isManual) :
		DepthBuffer(poolId, 0, width, height, fsaa, "", isManual),
		mCreatorContext(creatorContext),
		mDepthBuffer(depth),
		mStencilBuffer(stencil),
		mMultiSampleQuality(multiSampleQuality),
		mRenderSystem(renderSystem)
	{
		if (mDepthBuffer)
		{
			switch(mDepthBuffer->getGLFormat())
			{
#if GL_OES_framebuffer_object
			case GL_DEPTH_COMPONENT16_OES:
				mBitDepth = 16;
				break;
#endif

#if GL_OES_depth24
			case GL_DEPTH_COMPONENT24_OES
				mBitDepth = 32;
				break;
#endif
			}
		}
	}
	
	GLESDepthBuffer::~GLESDepthBuffer()
	{
		if (mStencilBuffer && mStencilBuffer != mDepthBuffer)
		{
			delete mStencilBuffer;
			mStencilBuffer = 0;
		}
		
		if (mDepthBuffer)
		{
			delete mDepthBuffer;
			mDepthBuffer = 0;
		}
	}
	
	bool GLESDepthBuffer::isCompatible(RenderTarget* renderTarget) const
	{
		bool retVal = false;
		
		if (mRenderSystem->getCapabilities()->hasCapability(RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL))
		{
			if (!mDepthBuffer::isCompatible(renderTarget))
				return false;
		}
		else
		{
			if (this->getWidth() != renderTarget->getWidth() ||
				this->getHeight() != renderTarget->getHeight() ||
				this->getFSAA() != renderTarget->getFSAA())
					return false;
		}
		
		GLESFrameBufferObject* fbo = 0;
		renderTarget->getCustomAttribute("FBO", &fbo);
		
		if (!fbo)
		{
			GLESContext *windowContext;
			renderTarget->getCustomAttribute("GLCONTEXT", &windowContext);
			
			if (!mDepthBuffer && !mStencilBuffer && mCreatorContext == windowContext)
				retVal = true;
		}
		else
		{
			if (mDepthBuffer || mStencilBuffer)
			{
				GLenum internalFormat = fbo->getFormat();
				GLenum depthFormat, stencilFormat;
				mRenderSystem->_getDepthStencilFormatFor(internalFormat, &depthFormat, &stencilFormat);
				
				bool bSameDepth = false;
				
				if (mDepthBuffer)
					bSameDepth |= mDepthBuffer->getGLFormat() == depthFormat;
					
				bool bSameStencil = false;
				
				if (!mStencilBuffer || mStencilBuffer == mDepthBuffer)
					bSameStencil = stencilFormat == GL_NONE;
				else
				{
					if (mStencilBuffer)
						bSameStencil = stencilFormat == mStencilBuffer->getGLFormat();
				}
				
				retVal = bSameDepth && bSameStencil;
			}
		}
		
		return retVal;
	}
}
